package com.shiguiwu.springboot3.service;

import com.shiguiwu.springboot3.dto.AuthUser;
import com.shiguiwu.springboot3.dto.request.RegisterRequest;
import com.shiguiwu.springboot3.entity.Member;
import com.shiguiwu.springboot3.mapper.MemberMapper;
import com.shiguiwu.springboot3.util.ServletUtil;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * @description: member service
 * @author: stone
 * @date: Created by 2025/9/22 15:01
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springboot3.service
 */
@Service
public class MemberService  implements UserDetailsService {

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Example example = new Example(Member.class);
        example.createCriteria().andEqualTo("username", username)
                .orEqualTo("email", username);

        Member member = memberMapper.selectOneByExample(example);
        if(member == null){
            throw new UsernameNotFoundException(username);
        }

        //验证密码
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (!passwordEncoder.matches(authentication.getCredentials().toString(), member.getPasswordHash())) {

            throw new RuntimeException("密码错误");
        }

        AuthUser authUser = new AuthUser();
        authUser.setUsername(member.getUsername());
        authUser.setPassword(member.getPasswordHash());
        authUser.setStatus(member.getStatus());
        authUser.setMobile(member.getMobile());
        authUser.setId(member.getId());

        authUser.setAvatarUrl(member.getAvatarUrl());
        SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(authUser, null, authUser.getAuthorities()));
        return authUser;
    }

    public AuthUser authenticate(String username, String password) {
        UserDetails userDetails = this.loadUserByUsername(username);

        AuthUser authUser = (AuthUser) userDetails;
        if (!passwordEncoder.matches(password, authUser.getPassword())) {

            throw new RuntimeException("密码错误");
        }

        return authUser;
    }

    public Long register(@Valid RegisterRequest registerRequest) {
        Example example = new Example(Member.class);

        example.createCriteria()
                .andEqualTo("username", registerRequest.getUsername())
                .orEqualTo("email", registerRequest.getEmail())
                .orEqualTo("mobile", registerRequest.getMobile());


        Member member = memberMapper.selectOneByExample(example);
        // 1. 检查用户名和邮箱是否已存在
        if (member != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 2. 创建新用户实体，并使用BCrypt加密密码（切勿明文存储！）[3,5](@ref)
        member  = new  Member();
        member.setUsername(registerRequest.getUsername());
        member.setEmail(registerRequest.getEmail());
        member.setPasswordHash(passwordEncoder.encode(registerRequest.getPassword())); // 核心安全步骤
        member.setMobile(registerRequest.getMobile());
        member.setStatus(1); // 设置账户状态为激活
        member.setRegistrationDate(LocalDateTime.now());

        // 3. 保存用户
        memberMapper.save(member);
        return member.getId();
    }

}
